package com.guarantee.server;

import com.guarantee.server.config.GuaranteeConfig;
import lombok.extern.log4j.Log4j2;
import org.apache.catalina.connector.Connector;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.scheduling.annotation.EnableScheduling;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.TimeZone;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author huisonglin
 * @Description
 * @PackageName guarantee-server
 * @Package com.guarantee.server
 * @Date 2022/9/23 14:27
 * @Version 1.0
 */
@SpringBootApplication
@MapperScan("com.guarantee.server.**.mapper")
@EnableConfigurationProperties(GuaranteeConfig.class)
@EnableScheduling
@Log4j2
public class RestApplication {

    public static void main(String[] args) {
        while (!isInternetAvailable()) {
            // 等待直到网络连通，可以添加一些延时以避免过度轮询
            try {
                Thread.sleep(1000); // 等待1秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Waiting for network connection...");
        }
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        SpringApplication.run(RestApplication.class, args);
        System.out.println(" ,----.     ,--,                                ,---,                       \n" +
                " /   /  \\-.,--.'|         ,---,                ,---.'|               ,---.   \n" +
                "|   :    :||  |,      ,-+-. /  |  ,----._,.    |   | :              '   ,'\\  \n" +
                "|   | .\\  .`--'_     ,--.'|'   | /   /  ' /    |   | |   ,--.--.   /   /   | \n" +
                ".   ; |:  |,' ,'|   |   |  ,\"' ||   :     |  ,--.__| |  /       \\ .   ; ,. : \n" +
                "'   .  \\  |'  | |   |   | /  | ||   | .\\  . /   ,'   | .--.  .-. |'   | |: : \n" +
                " \\   `.   ||  | :   |   | |  | |.   ; ';  |.   '  /  |  \\__\\/: . .'   | .; : \n" +
                "  `--'\"\"| |'  : |__ |   | |  |/ '   .   . |'   ; |:  |  ,\" .--.; ||   :    | \n" +
                "    |   | ||  | '.'||   | |--'   `---`-'| ||   | '/  ' /  /  ,.  | \\   \\  /  \n" +
                "    |   | :;  :    ;|   |/       .'__/\\_: ||   :    :|;  :   .'   \\ `----'   \n" +
                "    `---'.||  ,   / '---'        |   :    : \\   \\  /  |  ,     .-./          \n" +
                "      `---` ---`-'                \\   \\  /   `----'    `--`---'              ");
    }

    public static boolean isInternetAvailable() {
        try (Socket sock = new Socket()) {
            sock.connect(new InetSocketAddress("www.baidu.com", 80), 1000); // 尝试连接到Google的80端口，超时1秒
            return true;
        } catch (IOException e) {
            return false;
        }
    }
//    /**
//     * 用于接受 shutdown 事件
//     */
//    @Bean
//    public GracefulShutdown gracefulShutdown() {
//        return new GracefulShutdown();
//    }
//
//    @Bean
//    public ServletWebServerFactory servletContainer() {
//        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
//        tomcat.addConnectorCustomizers(gracefulShutdown());
//        return tomcat;
//    }
//
//    /**
//     * 优雅关闭 Spring Boot
//     */
//    private static class GracefulShutdown implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> {
//        private volatile Connector connector;
//
//
//        //获取tomcat的connector
//        @Override
//        public void customize(Connector connector) {
//            this.connector = connector;
//        }
//
//        //监听事件
//        @Override
//        public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
//            //拒绝停机操作的后续请求
//            this.connector.pause();
//            log.info("停止Tomcat connector, 拒绝接收后续请求");
//            //获取对应线程池并做对应类型判断,true则开始优雅关闭
//            Executor executor = this.connector.getProtocolHandler().getExecutor();
//            if (executor instanceof ThreadPoolExecutor) {
//                try {
//                    ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
//                    //开始关闭线程池
//                    threadPoolExecutor.shutdown();
//                    log.info("开始关闭线程池");
//                    //最大宽限时间
//                    int waitTime = 30;
//                    //若线程池中有未完成事件,等待完成后关闭,若超过最大宽限时间未完成,强制关闭;
//                    //若没有未完成事件,直接关闭
//                    if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {
//                        log.info("Tomcat线程池无法在"+waitTime+"s 内优雅关闭. 强制结束");
//                    }
//                } catch (InterruptedException ex) {
//                    Thread.currentThread().interrupt();
//                }
//            }
//        }
//    }
}
